package com.cfweb.controller.app;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.cfweb.api.ServiceApi;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.CfServiceBrokerMapper;
import com.cfweb.dao.CfServiceInstanceMapper;
import com.cfweb.dao.CfServiceMapper;
import com.cfweb.domain.CfService;
import com.cfweb.domain.CfServiceExample;
import com.cfweb.domain.CfServiceInstance;
import com.cfweb.domain.CfServiceInstanceExample;
import com.cfweb.pojo.CfServiceInstanceWithType;
import com.cfweb.pojo.DatabaseServiceWithBroker;
import com.cfweb.util.DbUtil;
import com.cfweb.util.ExtJSResponse;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author (yufangjiang) Dec 2, 2014
 */
@Service
@Path("/service")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ServiceManagement {

	/**
	 * 服务实例名称的长度
	 */
	public static Integer SERVICE_INSTANCE_NAME_LENGTH = 5;

	/**
	 * session
	 */
	@Autowired
	private HttpSession session;
	/**
	 * 服务
	 */
	@Autowired
	private CfServiceMapper cfsMapper;
	/**
	 * 服务实例
	 */
	@Autowired
	private CfServiceInstanceMapper serviceMapper;
	/**
	 * servicebroker
	 */
	@Autowired
	private CfServiceBrokerMapper cfsBrokerMapper;

	/**
	 * 根据服务类型获取服务实例
	 * 
	 * @param category
	 *            第一大類（数据库服务、应用服务 &）
	 * @param subcategory
	 *            第二大类（oracle、mysql &）
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Path("/list")
	@GET
	public ExtJSResponse list(@QueryParam("first") String category, @QueryParam("second") String subcategory)
			throws Exception {
		Integer cat = null;
		Integer subcat = null;
		if (StringUtil.isNotEmpty(category)) {
			cat = Integer.valueOf(category);
		}

		if (StringUtil.isNotEmpty(subcategory)) {
			subcat = Integer.valueOf(subcategory);
		}

		List<CfServiceInstanceWithType> services = serviceMapper.selectServiceByParams(cat, subcat,
				(String) session.getAttribute(LoginHandler.ORG), (String) session.getAttribute(LoginHandler.SPACE));
		Map<String, CfServiceInstanceWithType> servicesMap = new HashMap<String, CfServiceInstanceWithType>();
		for (CfServiceInstanceWithType service : services) {
			servicesMap.put(service.getServiceInstanceName(), service);
		}

		List<CfServiceInstanceWithType> response = new ArrayList<>();
		for (Map<String, Object> cs : ServiceApi.getServices(session)) {
			String name = (String) ((Map<String, Object>) cs.get("entity")).get("name");
			if (servicesMap.containsKey(name)) {
				response.add(servicesMap.get(name));
			}
		}
		return ExtJSResponse.successResWithData(response);
	}

	/**
	 * 列出集群支持的服务
	 * 
	 * @param type
	 * @return
	 */
	@Path("/listall")
	@GET
	public ExtJSResponse listall(@QueryParam("type") Integer type) {
		CfServiceExample example = new CfServiceExample();
		if (type != null) {
			example.createCriteria().andSerTypeEqualTo(type);
		}
		List<CfService> ls = cfsMapper.selectByExample(example);
		List<Map<String, Object>> list = new ArrayList<>();
		for (CfService cfs : ls) {
			Map<String, Object> map = new HashMap<String, Object>();
			List<String> cfsb = cfsBrokerMapper.selectByServiceId(cfs.getId());
			map.put("id", cfs.getId());
			map.put("serName", cfs.getSerName());
			map.put("serImg", cfs.getSerImg());
			map.put("serLargeImg", cfs.getSerLargeImg());
			map.put("serPrefix", cfs.getSerPrefix());
			map.put("serDesCn", cfs.getSerDescChn());
			map.put("serDesEng", cfs.getSerDescEng());
			map.put("brokers", cfsb);
			if (cfsb.size() == 1 && cfsb.get(0) == null || cfsb.size() == 0) {
				map.put("type", 0);
			} else {
				map.put("type", 1);
			}
			list.add(map);
		}
		return ExtJSResponse.successResWithData(list);
	}

	/**
	 * 根据guid获取servicebroker
	 * 
	 * @param lguid
	 *            以“，”分割的guid字符串
	 * @return
	 * @throws Exception
	 */
	@Path("/listforbroker")
	@GET
	public ExtJSResponse listforbroker(@QueryParam("lguid") String lguid) throws Exception {
		System.out.println(lguid);
		String[] lg = lguid.split(",");
		List<Map<String, Object>> lr = new ArrayList<Map<String, Object>>();
		for (String guid : lg) {
			List<Map<String, Object>> tlr = ServiceApi.listServiceBroker(session, guid);
			if (tlr != null) {
				lr.addAll(tlr);
			}
		}
		return ExtJSResponse.successResWithData(lr);
	}

	/**
	 * 创建servicebroker
	 * 
	 * @param name
	 * @param url
	 * @return
	 */
	@Path("/createbroker")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse createbroker(@FormParam("name") String name, @FormParam("url") String url) {
		// CloudFoundryClient client = (CloudFoundryClient)
		// session.getAttribute(LoginHandler.CLIENT);
		// CloudServiceBroker csb = new CloudServiceBroker(USERNAME, PASSWORD,
		// url);
		// csb.setName(name);
		// client.createServiceBroker(csb);
		return ExtJSResponse.successRes();
	}

	/**
	 * 更新servicebroker
	 * 
	 * @param name
	 * @param url
	 * @return
	 */
	@Path("/updatebroker")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse updatebroker(@FormParam("name") String name, @FormParam("url") String url) {
		// CloudFoundryClient client = (CloudFoundryClient)
		// session.getAttribute(LoginHandler.CLIENT);
		// CloudServiceBroker csb = new CloudServiceBroker(USERNAME, PASSWORD,
		// url);
		// csb.setName(name);
		// client.updateServiceBroker(csb);
		return ExtJSResponse.successRes();
	}

	/**
	 * 删除servicebroker
	 * 
	 * @param name
	 * @return
	 */
	@Path("/deletebroker")
	@GET
	public ExtJSResponse deletebroker(@QueryParam("name") String name) {
		// CloudFoundryClient client = (CloudFoundryClient)
		// session.getAttribute(LoginHandler.CLIENT);
		// client.deleteServiceBroker(name);
		return ExtJSResponse.successRes();
	}

	/**
	 * serviceplan更新为public
	 * 
	 * @param name
	 * @param visibility
	 * @return
	 */
	@Path("/updateVisibility")
	@GET
	public ExtJSResponse updateVisibility(@QueryParam("name") String name,
			@QueryParam("visibility") boolean visibility) {
		// CloudFoundryClient client = (CloudFoundryClient)
		// session.getAttribute(LoginHandler.CLIENT);
		// client.updateServicePlanVisibilityForBroker(name, visibility);
		return ExtJSResponse.successRes();
	}

	/**
	 * 创建服务实例
	 * 
	 * @param service
	 * @param plan
	 * @param planId
	 * @param prefix
	 * @param typeId
	 * @param visibility
	 * @return
	 * @throws Exception
	 */
	@Path("/createinstance")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse createInstance(@FormParam("service") String service, @FormParam("plan") String plan,
			@FormParam("planId") String planId, @FormParam("prefix") String prefix, @FormParam("typeId") Integer typeId,
			@FormParam("visibility") boolean visibility) throws Exception {
		String name = prefix + "_" + "" + produceServiceName(SERVICE_INSTANCE_NAME_LENGTH);
		if (ServiceApi.createServiceInstance(session, service, planId, name, visibility)) {
			CfServiceInstance serviceIns = new CfServiceInstance();
			serviceIns.setCreateTime(new Date());
			serviceIns.setService(service);
			serviceIns.setPlan(plan);
			serviceIns.setUpdateTime(new Date());
			serviceIns.setServiceInstanceName(name);
			serviceIns.setOrg((String) session.getAttribute(LoginHandler.ORG));
			serviceIns.setSpace((String) session.getAttribute(LoginHandler.SPACE));
			serviceIns.setServiceTypeId(typeId);
			// 设置状态为2，并且获取host等信息
			serviceIns.setState(2);
			Connection connection = null;
			PreparedStatement statement = null;
			ResultSet rs = null;
			try {
				connection = DbUtil.getConnection();
				statement = connection.prepareStatement("select host,port,user from sb_instances where service = ?");
				statement.setString(1, serviceIns.getServiceInstanceName());
				rs = statement.executeQuery();
				while (rs.next()) {
					serviceIns.setHost(rs.getString(1));
					serviceIns.setPort(rs.getInt(2));
					serviceIns.setUser(rs.getString(3));
				}
			} catch (Exception e) {
				throw e;
			} finally {
				DbUtil.close(rs);
				DbUtil.close(connection);

			}
			serviceMapper.insert(serviceIns);
		}
		return ExtJSResponse.successRes();
	}

	/**
	 * 删除服务实例
	 * 
	 * @param serviceName
	 * @return
	 * @throws Exception
	 */
	@Path("/deleteinstance")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse deleteInstance(@FormParam("serviceName") String serviceName) throws Exception {
		ServiceApi.deleteServiceInstance(serviceName, session);
		CfServiceInstanceExample example = new CfServiceInstanceExample();
		example.createCriteria().andServiceEqualTo(serviceName);
		serviceMapper.deleteByExample(example);
		return ExtJSResponse.successRes();
	}

	/**
	 * 自动生成服务实例的名称
	 * 
	 * @param length
	 * @return
	 */
	public static String produceServiceName(int length) {
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * 获取服务
	 * 
	 * @param type
	 * @return
	 */
	@Path("/getDatabaseSer")
	@GET
	public ExtJSResponse getDatabaseSerBroker(@QueryParam("type") Integer type) {
		List<DatabaseServiceWithBroker> lsbroker = new ArrayList<DatabaseServiceWithBroker>();
		CfServiceExample example = new CfServiceExample();
		if (type != null) {
			example.createCriteria().andSerTypeEqualTo(type);
		}
		List<CfService> ls = cfsMapper.selectByExample(example);
		for (int i = 0; i < ls.size(); i++) {
			CfService cfs = ls.get(i);
			List<String> cfsb = cfsBrokerMapper.selectByServiceId(cfs.getId());
			DatabaseServiceWithBroker databaseWithBroker = new DatabaseServiceWithBroker();
			databaseWithBroker.setId(cfs.getId());
			databaseWithBroker.setSerName(cfs.getSerName());
			databaseWithBroker.setSerTemImg(cfs.getSerLargeImg());
			databaseWithBroker.setSerPrefix(cfs.getSerPrefix());
			databaseWithBroker.setBrokers(cfsb);
			if (cfsb.size() == 1 && cfsb.get(0) == null || cfsb.size() == 0) {
				databaseWithBroker.setType(0);
			} else {
				databaseWithBroker.setType(1);
			}
			lsbroker.add(databaseWithBroker);
		}
		return ExtJSResponse.successResWithData(lsbroker);
	}
}
